const { Service } = require('egg');
const { sm4 } = require('sm-crypto');
const { v4: uuidV4 } = require('uuid');
const moment = require('moment');
const user_table = 'user';
const user_role_table = 'user_role_relationship';
const role_table = 'role';
const address_table = 'address';

class UserService extends Service {

  // 查询用户基本信息
  async info(id) {
    try {
      const user = await this.app.knex
        .select('t1.uuid', 't1.name', 't1.sex', 't1.login_name', 't1.email', 't3.name as role', 't3.uuid as role_id')
        .from(`${user_table} as t1`)
        .leftJoin(`${user_role_table} as t2`, function() {
          this.on('t1.uuid', '=', 't2.user_id');
        })
        .leftJoin(`${role_table} as t3`, function() {
          this.on('t2.role_id', '=', 't3.uuid');
        })
        .whereRaw(`t1.uuid = ${id} and t2.is_delete = 0 `);


      const address = await this.app.knex.select('uuid as id', 'address', 'user_name', 'user_phone', 'user_email')
        .from(address_table)
        .whereRaw(`is_delete = 0 and uuid = ${id}`);

      const result = {
        ...user[0],
        address,
      };

      return result;
    } catch (error) {
      throw error;
    }
  }

  // 查询用户列表
  async list(name, login_name, sex, method = 'desc', order = 'create_time', pageIndex = 1, pageSize = 10) {
    try {

      const condition = {
        is_delete: 0,
      };

      if (name) {
        condition.name = name;
      }

      if (login_name) {
        condition.login_name = login_name;
      }

      if (sex) {
        condition.sex = sex;
      }

      const list = await this.app.knex
        .select('uuid', 'name', 'login_name', 'sex', 'email', 'create_time')
        .from(user_table)
        .where(condition)
        .orderBy(order, method)
        .limit(Number(pageSize))
        .offset((Number(pageIndex) - 1) * Number(pageSize));

      const count = await this.app.knex(user_table).count('uuid as id').where(condition);


      return {
        count: count[0].id,
        list,
      };
    } catch (error) {
      console.log(error);
      throw error;
    }
  }

  // 新增用户
  async insert(name, login_name, sex, password, phone, email) {
    try {
      const time = moment();
      const admin = this.ctx.session;

      const is_repeat = await this.app.knex(user_table).select('uuid').where({ login_name, is_delete: 1 });
      if (!is_repeat) {
        throw new Error('登录名重复');
      }
      password = sm4.encrypt(password, this.config.sm.key, { mode: this.config.sm.mode, iv: this.config.sm.iv });

      const instance = {
        name, login_name, sex, email, phone, password,
        uuid: uuidV4(),
        create_by: admin.id,
        update_by: admin.id,
        create_time: moment(time).format('YYYY-MM-DD HH:mm:ss'),
        update_time: moment(time).format('YYYY-MM-DD HH:mm:ss'),
        is_delete: 0,
      };

      const data = await this.app.knex(user_table).insert(instance).returning('id');


      instance.id = data[0];
      return instance;
    } catch (error) {
      throw error;
    }
  }

  // 更新用户
  async update(id, name, sex, phone, email) {
    try {
      const user = this.ctx.session;
      const time = moment();
      const [ instance ] = await this.app.knex.select('*').from(user_table)
        .where({ uuid: id, is_delete: 0 });

      if (name) {
        instance.name = name;
      }

      if (sex) {
        instance.sex = sex;
      }

      if (phone) {
        instance.phone = phone;
      }

      if (email) {
        instance.email = email;
      }

      instance.update_time = moment(time).format('YYYY-MM-DD HH:mm:ss');
      instance.update_by = user.id;

      await this.app.knex(user_table).update(instance).where({ uuid: id });

      return instance;
    } catch (error) {
      throw error;
    }
  }

  // 删除用户
  async delete(ids) {
    try {
      const time = moment();
      const { id } = this.ctx.session;
      const is_exist = ids.find(f => {
        return f === '-1';
      });

      if (is_exist) {
        throw new Error('不能删除超级管理员');
      }
      await this.app.knex(user_table)
        .update({ is_delete: 1, update_time: moment(time).format('YYYY-MM-DD HH:mm:ss'), update_by: id })
        .whereIn('uuid', ids)
        .andWhere({ is_delete: 0 });
      return;
    } catch (error) {
      throw error;
    }
  }

  // 忘记密码
  async forgetPassword(newPassword) {
    try {
      const time = moment();
      const { id } = this.ctx.session;

      const update_value = {
        password: sm4.encrypt(newPassword, this.config.sm.key, { mode: this.config.sm.mode, iv: this.config.sm.iv }),
        update_by: id,
        update_time: moment(time).format('YYYY-MM-DD HH:mm:ss'),
      };

      await this.app.knex(user_table).update(update_value).where({ uuid: id, is_delete: 0 });

      return;
    } catch (error) {
      throw error;
    }
  }

  // 修改密码
  async changePassword(newPassword, user_id) {
    try {
      const time = moment();
      const { id } = this.ctx.session;

      const update_value = {
        password: sm4.encrypt(newPassword, this.config.sm.key, { mode: this.config.sm.mode, iv: this.config.sm.iv }),
        update_by: id,
        update_time: moment(time).format('YYYY-MM-DD HH:mm:ss'),
      };

      await this.app.knex(user_table).update(update_value).where({ uuid: user_id });

      return;
    } catch (error) {
      throw error;
    }
  }

  async register(name, login_name, password) {
    const ctx = this.ctx;
    try {

      const time = moment();

      if (!password) {
        password = sm4.encrypt('Admin@123456', this.config.sm.key, { mode: this.config.sm.mode, iv: this.config.sm.iv });
      }

      const instance = {
        name, login_name, password,
        sex: 1,
        email: '',
        phone: '',
        uuid: uuidV4(),
        create_by: '-1',
        update_by: '-1',
        create_time: moment(time).format('YYYY-MM-DD HH:mm:ss'),
        update_time: moment(time).format('YYYY-MM-DD HH:mm:ss'),
        is_delete: 0,
      };

      await this.app.knex(user_table).insert(instance);

      return instance;
    } catch (error) {
      throw error;
    }
  }


  async init() {
    const ctx = this.ctx;
    try {
      const time = moment();

      const is_exist = await ctx.app.knex(user_table).select('uuid').where({ login_name: 'superAdmin' })
        .first();
      if (is_exist) {
        throw new Error('初始化账户已经存在');
      }

      const password = sm4.encrypt('Admin@123456', this.config.sm.key, { mode: this.config.sm.mode, iv: this.config.sm.iv });

      const instance = {
        name: 'superAdmin',
        login_name: 'superAdmin',
        password,
        sex: 1,
        email: '',
        phone: '',
        uuid: uuidV4(),
        create_by: '-1',
        update_by: '-1',
        create_time: moment(time).format('YYYY-MM-DD HH:mm:ss'),
        update_time: moment(time).format('YYYY-MM-DD HH:mm:ss'),
        is_delete: 0,
      };

      await this.app.knex(user_table).insert(instance);

      return instance;
    } catch (error) {
      throw error;
    }
  }
}

module.exports = UserService;
